#include "ImaEmailNotifier.h"
#include "ImaLogger.h"
#include "ImaGlobals.h"
//#include "vmime/vmime.hpp"
//#include "vmime/platforms/posix/posixHandler.hpp"
#include "CertVerifier.h"
#include <string.h>

ImaEmailNotifier::ImaEmailNotifier(const std::string& strSmtpUrl, const std::string& strUsername, const std::string strPassword) 
		: mSmtpUrl(strSmtpUrl.c_str()), 
			mUsername(strUsername),
			mPassword(strPassword) {
	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::ImaEmailNotifier called");
//	mTransport = mSmtpSession->getTransport(mSmtpUrl);
	try {
		vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
		mSmtpSession = vmime::create <vmime::net::session>();
		mTransport = mSmtpSession->getTransport(mSmtpUrl);

		LOG(debug, __FILE__, __LINE__, "session and transport initialized successfully");
	} 
	// VMime exception
	catch (vmime::exception& e) {
	    std::cout << "vmime::exception: " << e.what() << std::endl;
       char log_msg[2048];
		 sprintf(log_msg, "Exception received while initializing SMPTP session. Error: %s", e.what());
		 LOG(error, __FILE__, __LINE__, log_msg);
	}

	// Standard exception
	catch (std::exception& e) {
	    std::cout << "std::exception: " << e.what() << std::endl;
       char log_msg[2048];
		 sprintf(log_msg, "Unknown Exception received while initializing SMPTP session. Error: %s", e.what());
		 LOG(error, __FILE__, __LINE__, log_msg);
	}

	LOG(debug, __FILE__, __LINE__, "returning from ImaEmailNotifier::ImaEmailNotifier");
}

ImaEmailNotifier::~ImaEmailNotifier() {
	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::~ImaEmailNotifier");
	mTransport->disconnect();
}

int ImaEmailNotifier::init() {
	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::init called");

	int retVal = 0;
	try {
		mTransport->setProperty("connection.tls", true);
		mTransport->setProperty("auth.username", mUsername.c_str());
		mTransport->setProperty("auth.password", mPassword.c_str());
		mTransport->setProperty("options.need-authentication", true);
		mTransport->setCertificateVerifier(vmime::create <interactiveCertificateVerifier>());
		mTransport->connect();
	}
	// VMime exception
	catch (vmime::exception& e) {
		char log_msg[1024];
		sprintf(log_msg, "Exception received; vmime::exception: %s", e.what());
		LOG(debug, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}
	// Standard exception
	catch (std::exception& e) {
		char log_msg[1024];
		sprintf(log_msg, "Exception received; std::exception: %s", e.what());
		LOG(debug, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	return retVal;
}

bool ImaEmailNotifier::notify(const ImaInfo* pInfo, std::vector<ImaRecipient*>& recipientVector) {
	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::notify called");

	bool retVal = true;
	char log_msg[1024];

	try {
		vmime::messageBuilder mb;

		int numOfEmailRecipients = 0;
		
		std::vector<ImaRecipient*>::iterator it = recipientVector.begin();
		while(it != recipientVector.end()) {
			char *pEmailAddress = (*it)->mRecipientEmailId;
			if(strlen(pEmailAddress)) {
				sprintf(log_msg, "Email being sent for info id %lu to %s", pInfo->mInfoId, pEmailAddress);
				LOG(debug, __FILE__, __LINE__, log_msg);
				mb.getRecipients().appendAddress(vmime::create<vmime::mailbox>(pEmailAddress));
				numOfEmailRecipients++;
			}
			it++;
		}

		if(numOfEmailRecipients == 0) {
			sprintf(log_msg, "No email recipients for info id: %lu", pInfo->mInfoId);
			LOG(debug, __FILE__, __LINE__, log_msg);
			return retVal;
		}

		char email_subj[256];
		//sprintf(email_subj, "Important message for you from %s", pInfo->mEmailId);
		snprintf(email_subj, 32, "Information for you from %s: %s", pInfo->mEmailId, pInfo->mStrInfo.c_str());
		mb.setSubject(vmime::text(email_subj));
		mb.setExpeditor(vmime::mailbox(mUsername));
		mb.getTextPart()->setText(vmime::create<vmime::stringContentHandler>(pInfo->mStrInfo.c_str()));

	//	if(pInfo->mediaType != IMA_INFO_MEDIA_TEXT) {
	//		// Adding an attachment
	//		vmime::ref <vmime::fileAttachment> a = vmime::create <vmime::fileAttachment>( "./ImaConstants.h", vmime::mediaType("application/octet-stream"), vmime::text("My first attachment"));
	//		
	//		a->getFileInfo().setFilename("attachment_file_name.txt");
	//		a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
	//		mb.attach(a);
	//	}

		// Construction
		vmime::ref <vmime::message> msg = mb.construct();
		
		mTransport->send(msg);
	}

	// VMime exception
	catch (vmime::exception& e) {
		char log_msg[1024];
		sprintf(log_msg, "Exception received; vmime::exception: %s", e.what());
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = false;
	}
	// Standard exception
	catch (std::exception& e) {
		char log_msg[1024];
		sprintf(log_msg, "Exception received; std::exception: %s", e.what());
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = false;
	}

	return retVal;
}


bool ImaEmailNotifier::notify(const char* pMsgSub, const char* pMsgBody, const char* pRecipientEmailId) {
	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::notify called");

	bool retVal = true;
	char log_msg[1024];

	if(strlen(pRecipientEmailId)) {
		try {
			vmime::messageBuilder mb;

			sprintf(log_msg, "Email being sent to %s with info subject %s", pRecipientEmailId, pMsgSub);
			LOG(debug, __FILE__, __LINE__, log_msg);
			mb.getRecipients().appendAddress(vmime::create<vmime::mailbox>(pRecipientEmailId));
			mb.setSubject(vmime::text(pMsgSub));
			mb.setExpeditor(vmime::mailbox(mUsername));
			mb.getTextPart()->setText(vmime::create<vmime::stringContentHandler>(pMsgBody));

			// Construction
			vmime::ref <vmime::message> msg = mb.construct();
			mTransport->send(msg);
		}
		// VMime exception
		catch (vmime::exception& e) {
			char log_msg[1024];
			sprintf(log_msg, "Exception received; vmime::exception: %s", e.what());
			LOG(error, __FILE__, __LINE__, log_msg);
			retVal = false;
		}
		// Standard exception
		catch (std::exception& e) {
			char log_msg[1024];
			sprintf(log_msg, "Exception received; std::exception: %s", e.what());
			LOG(error, __FILE__, __LINE__, log_msg);
			retVal = false;
		}
	}

	return retVal;
}


bool ImaEmailNotifier::notify(const char* pRecipientEmailId, const char* pSenderName,
		const char* pSenderEmail, const char* pMsgSub, const char* pMsgBody) {
	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::notify called");

	bool retVal = true;
	char log_msg[1024];

	if(strlen(pRecipientEmailId)) {
		try {
			vmime::messageBuilder mb;

			sprintf(log_msg, "Email being sent to %s with info subject %s", pRecipientEmailId, pMsgSub);
			LOG(debug, __FILE__, __LINE__, log_msg);
			mb.getRecipients().appendAddress(vmime::create<vmime::mailbox>(pRecipientEmailId));
			mb.setSubject(vmime::text(pMsgSub));
			mb.setExpeditor(vmime::mailbox(mUsername));
			mb.getTextPart()->setText(vmime::create<vmime::stringContentHandler>(pMsgBody));

			// Construction
			vmime::ref <vmime::message> msg = mb.construct();
			mTransport->send(msg);
		}
		// VMime exception
		catch (vmime::exception& e) {
			char log_msg[1024];
			sprintf(log_msg, "Exception received; vmime::exception: %s", e.what());
			LOG(error, __FILE__, __LINE__, log_msg);
			retVal = false;
		}
		// Standard exception
		catch (std::exception& e) {
			char log_msg[1024];
			sprintf(log_msg, "Exception received; std::exception: %s", e.what());
			LOG(error, __FILE__, __LINE__, log_msg);
			retVal = false;
		}
	}
	return retVal;

}


//bool ImaEmailNotifier::notify() {
//	LOG(debug, __FILE__, __LINE__, "ImaEmailNotifier::notify called");
//
//	bool retVal = true;
//
//	try {
//		// VMime initialization
//		vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
//
//		vmime::messageBuilder mb;
//		mb.setSubject(vmime::text("Message subject"));
//		mb.setExpeditor(vmime::mailbox("hello.kr.dev@gmail.com"));
//		mb.getRecipients().appendAddress(vmime::create<vmime::mailbox>("kamal.nandan@gmail.com"));
//		mb.getTextPart()->setText(vmime::create<vmime::stringContentHandler>("Message with attachment"));
//
//		vmime::utility::url url("smtp://smtp.gmail.com");
//		vmime::ref <vmime::net::session> session = vmime::create <vmime::net::session>();
//		vmime::ref <vmime::net::transport> tr = session->getTransport(url);
//		tr->setProperty("connection.tls", true);
//		tr->setProperty("auth.username", "hello.kr.dev@gmail.com");
//		tr->setProperty("auth.password", "download@256");
//		tr->setProperty("options.need-authentication", true);
//		printf("Hi...1\n");
//		tr->setCertificateVerifier(vmime::create <interactiveCertificateVerifier>());
////Attachment
//      // Adding an attachment
//      vmime::ref <vmime::fileAttachment> a = vmime::create <vmime::fileAttachment>
//      (
//         "./ImaConstants.h",                               // full path to file
//         vmime::mediaType("application/octet-stream"),   // content type
//         vmime::text("My first attachment")              // description
//      );
//
//      a->getFileInfo().setFilename("example2.cpp");
//      a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
//
//      mb.attach(a);
////
//
//
//		// Construction
//		vmime::ref <vmime::message> msg = mb.construct();
//		printf("Hi...2\n");
//		
//		tr->connect();
//		printf("Hi...3\n");
//		tr->send(msg);
//		printf("Hi...4\n");
//		tr->disconnect();
//	}
//	// VMime exception
//	catch (vmime::exception& e) {
//	    std::cout << "vmime::exception: " << e.what() << std::endl;
//	    return false;
//	}
//
//	// Standard exception
//	catch (std::exception& e) {
//	    std::cout << "std::exception: " << e.what() << std::endl;
//	    return false;
//	}
//
//	return retVal;
//}


